package cn.android666.net.util

import com.google.gson.internal.GsonTypes
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

/** 请求回调接口，泛型T为希望请求返回的数据类型 */
abstract class ApiRequestCallback<T> {

    /** 用于保存ApiRequestCallback<T>中的T的真实类型 */
    var type: Type

    init {
        // 获取ApiRequestCallback<T>中的T的真实类型
        type = getSuperclassTypeParameter(javaClass)
    }

    private fun getSuperclassTypeParameter(subclass: Class<*>): Type {
        // subclass   子类，比如：MyApiRequestCallback<LoginBean>
        // superclass 父类，比如：ApiRequestCallback<LoginBean>
        val superclass = subclass.genericSuperclass
        if (superclass is Class<*>) {
            throw RuntimeException("Missing type parameter.")
        }
        // ParameterizedType翻译为“参数化类型”，即这个类型是带有参数的，说白了就是带泛型的类型
        // 如：Collection<String>是一个参数化类型
        // Type Arguments翻译为“类型参数”，即类型的参数，如Collection<String>是一个类型，这个类型的参数为String，参数可以有多个。
        // Parameter和Arguments都是参数的意思
        val parameterized = superclass as ParameterizedType  // 把Type转换为ParameterizedType，得到类型：ApiRequestCallback<LoginBean>

        // 得到ApiRequestCallback<LoginBean>中的LoginBean
        val javaBeanType = GsonTypes.canonicalize(parameterized.actualTypeArguments[0])
        return javaBeanType
    }

    /**
     * 请求成功时回调此方法，当RequestResult参数不为空，且RequestResult.success属性为true时才会调用此方法
     * @param requestResult 请求结果
     * @param baseResult 封装了基本的请求结果：code、msg、success，有时候需要用到这些信息时就可以从这里取
     *
     */
    abstract fun onApiRequestSuccess(requestResult: T, baseResult: RequestResult<*>?)

    /**
     * 请求失败时回调此方法，参数failCause为失败的原因
     * @param failCause 请求失败的原因
     * @param baseResult 封装了基本的请求结果：code、msg、success，有时候需要用到这些信息时就可以从这里取
     */
    abstract fun onApiRequestFail(failCause: String, baseResult: RequestResult<*>?)

}